home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 39 / Amiga Format CD39 (1999-04-13)(Future Publishing)(GB)[!][issue 1999-05].iso / -seriously_amiga- / graphics / ripley / source / recon.c < prev    next >
C/C++ Source or Header  |  1999-03-02  |  23KB  |  817 lines

  1. /* Predict.c, motion compensation routines                                    */
  2.  
  3. /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
  4.  
  5.  
  6.  
  7. /*
  8.  * Disclaimer of Warranty
  9.  *
  10.  * These software programs are available to the user without any license fee or
  11.  * royalty on an "as is" basis.  The MPEG Software Simulation Group disclaims
  12.  * any and all warranties, whether express, implied, or statuary, including any
  13.  * implied warranties or merchantability or of fitness for a particular
  14.  * purpose.  In no event shall the copyright-holder be liable for any
  15.  * incidental, punitive, or consequential damages of any kind whatsoever
  16.  * arising from the use of these programs.
  17.  *
  18.  * This disclaimer of warranty extends to the user of these programs and user's
  19.  * customers, employees, agents, transferees, successors, and assigns.
  20.  *
  21.  * The MPEG Software Simulation Group does not represent or warrant that the
  22.  * programs furnished hereunder are free of infringement of any third-party
  23.  * patents.
  24.  *
  25.  * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
  26.  * are subject to royalty fees to patent holders.  Many of these patents are
  27.  * general enough such that they are unavoidable regardless of implementation
  28.  * design.
  29.  *
  30.  */
  31.  
  32. #include <stdio.h>
  33.  
  34. #include "config.h"
  35. #include "global.h"
  36. #include "commandline.h"
  37.  
  38.  
  39. struct fpdata
  40. {
  41.     //    do not change or reorder the first
  42.     //  8 parameters!!!
  43.  
  44.      unsigned short h;
  45.      unsigned short w;
  46.     unsigned short lx2;
  47.     short y;
  48.     short x;
  49.     unsigned short lx;
  50.     short dx;
  51.     short dy;
  52.  
  53.     unsigned char **src;
  54.     unsigned char **dst;
  55.     short sfield;
  56.     short dfield;
  57.  
  58.     short average;
  59.  
  60. };
  61.     
  62.  
  63. #ifdef ASSEMBLER_OPTIMIZATION
  64.  
  65.     #include "fcprediction.h"
  66.  
  67. #else
  68.  
  69.     static void form_prediction(struct fpdata *f, int average_flag);
  70.     static void form_component_prediction _ANSI_ARGS_((unsigned char *src, unsigned char *dst,
  71.       int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int average_flag));
  72.  
  73. #endif
  74.  
  75.  
  76.  
  77.  
  78.  
  79. void form_predictions(bx,by,macroblock_type,motion_type,PMV,motion_vertical_field_select,dmvector,stwtype)
  80. int bx, by;
  81. int macroblock_type;
  82. int motion_type;
  83. int PMV[2][2][2], motion_vertical_field_select[2][2], dmvector[2];
  84. int stwtype;
  85. {
  86.  
  87.   struct fpdata fpdata;
  88.  
  89.   int currentfield;
  90.   unsigned char **predframe;
  91.   int DMV[2][2];
  92.   int stwtop, stwbot;
  93.  
  94.  
  95.   stwtop = stwtype%3; /* 0:temporal, 1:(spat+temp)/2, 2:spatial */
  96.   stwbot = stwtype/3;
  97.  
  98.   fpdata.x = bx;
  99.   fpdata.w = 16;
  100.  
  101.   if ((macroblock_type & MACROBLOCK_MOTION_FORWARD) 
  102.    || (picture_coding_type==P_TYPE))
  103.   {
  104.     if (picture_structure==FRAME_PICTURE)
  105.     {
  106.       fpdata.src = forward_reference_frame;
  107.       fpdata.dst = current_frame;
  108.       fpdata.lx2 = Coded_Picture_Width<<1;
  109.       fpdata.h = 8;
  110.  
  111.       if ((motion_type==MC_FRAME) 
  112.         || !(macroblock_type & MACROBLOCK_MOTION_FORWARD))
  113.       {
  114.         fpdata.lx = Coded_Picture_Width;
  115.         fpdata.y = by;
  116.         fpdata.dx = PMV[0][0][0];
  117.         fpdata.dy = PMV[0][0][1];
  118.  
  119.         if (stwtop<2)
  120.         {
  121.             fpdata.sfield = 0;
  122.             fpdata.dfield = 0;
  123.             form_prediction(&fpdata, stwtop);
  124. //          form_prediction(forward_reference_frame,0,current_frame,0,
  125. //            Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
  126. //            PMV[0][0][0],PMV[0][0][1],stwtop);
  127.         }
  128.  
  129.         if (stwbot<2)
  130.         {
  131.             fpdata.sfield = 1;
  132.             fpdata.dfield = 1;
  133.             form_prediction(&fpdata, stwbot);
  134.  
  135. //          form_prediction(forward_reference_frame,1,current_frame,1,
  136. //            Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
  137. //            PMV[0][0][0],PMV[0][0][1],stwbot);
  138.         }
  139.  
  140.       }
  141.       else if (motion_type==MC_FIELD) /* field-based prediction */
  142.       {
  143.         /* top field prediction */
  144.  
  145.         fpdata.sfield = motion_vertical_field_select[0][0];
  146.         fpdata.dfield = 0;
  147.         fpdata.lx = Coded_Picture_Width<<1;
  148.         fpdata.y = by>>1;
  149.         fpdata.dx = PMV[0][0][0];
  150.         fpdata.dy = PMV[0][0][1] >> 1;
  151.  
  152.         if (stwtop<2)
  153.         {
  154.             form_prediction(&fpdata, stwtop);
  155. //          form_prediction(forward_reference_frame,motion_vertical_field_select[0][0],
  156. //            current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
  157. //            bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,stwtop);
  158.         }
  159.  
  160.         /* bottom field prediction */
  161.         if (stwbot<2)
  162.         {
  163.             fpdata.sfield = motion_vertical_field_select[1][0];
  164.             fpdata.dfield = 1;
  165.             fpdata.dx = PMV[1][0][0];
  166.             fpdata.dy = PMV[1][0][1] >> 1;
  167.  
  168.             form_prediction(&fpdata, stwbot);
  169. //          form_prediction(forward_reference_frame,motion_vertical_field_select[1][0],
  170. //            current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
  171. //            bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,stwbot);
  172.         }
  173.       }
  174.       else if (motion_type==MC_DMV) /* dual prime prediction */
  175.       {
  176.         /* calculate derived motion vectors */
  177.         Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1);
  178.  
  179.         fpdata.lx = Coded_Picture_Width<<1;
  180.         fpdata.y = by>>1;
  181.  
  182.         if (stwtop<2)
  183.         {
  184.           /* predict top field from top field */
  185.  
  186.             fpdata.sfield = 0;
  187.             fpdata.dfield = 0;
  188.             fpdata.dx = PMV[0][0][0];
  189.             fpdata.dy = PMV[0][0][1] >> 1;
  190.  
  191.             form_prediction(&fpdata, 0);
  192.        //   form_prediction(forward_reference_frame,0,current_frame,0,
  193.        //     Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
  194.        //     PMV[0][0][0],PMV[0][0][1]>>1,0);
  195.  
  196.             fpdata.sfield = 1;
  197.             fpdata.dx = DMV[0][0];
  198.             fpdata.dy = DMV[0][1];
  199.  
  200.             form_prediction(&fpdata, 1);
  201.  
  202.           /* predict and add to top field from bottom field */
  203.        //   form_prediction(forward_reference_frame,1,current_frame,0,
  204.        //     Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
  205.        //     DMV[0][0],DMV[0][1],1);
  206.         }
  207.  
  208.         if (stwbot<2)
  209.         {
  210.             fpdata.sfield = 1;
  211.             fpdata.dfield = 1;
  212.             fpdata.dx = PMV[0][0][0];
  213.             fpdata.dy = PMV[0][0][1] >> 1;
  214.  
  215.             form_prediction(&fpdata, 0);
  216.  
  217. //          /* predict bottom field from bottom field */
  218. //          form_prediction(forward_reference_frame,1,current_frame,1,
  219. //            Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
  220. //            PMV[0][0][0],PMV[0][0][1]>>1,0);
  221.  
  222.             fpdata.sfield = 0;
  223.             fpdata.dx = DMV[1][0];
  224.             fpdata.dy = DMV[1][1];
  225.  
  226.             form_prediction(&fpdata, 1);
  227.  
  228.           /* predict and add to bottom field from top field */
  229. //          form_prediction(forward_reference_frame,0,current_frame,1,
  230. //            Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1,
  231. //            DMV[1][0],DMV[1][1],1);
  232.         }
  233.       }
  234. //      else
  235. //        /* invalid motion_type */
  236. //        printf("invalid motion_type\n");
  237.     }
  238.     else /* TOP_FIELD or BOTTOM_FIELD */
  239.     {
  240.       fpdata.dst = current_frame;
  241.       fpdata.lx2 = Coded_Picture_Width<<1;
  242.       fpdata.lx = Coded_Picture_Width<<1;
  243.       fpdata.dfield = 0;
  244.  
  245.       /* field picture */
  246.       currentfield = (picture_structure==BOTTOM_FIELD);
  247.  
  248.       /* determine which frame to use for prediction */
  249.       if ((picture_coding_type==P_TYPE) && Second_Field
  250.          && (currentfield!=motion_vertical_field_select[0][0]))
  251.         predframe = backward_reference_frame; /* same frame */
  252.       else
  253.         predframe = forward_reference_frame; /* previous frame */
  254.  
  255.       fpdata.src = predframe;
  256.  
  257.       if ((motion_type==MC_FIELD)
  258.         || !(macroblock_type & MACROBLOCK_MOTION_FORWARD))
  259.       {
  260.         /* field-based prediction */
  261.         if (stwtop<2)
  262.         {
  263.             fpdata.sfield = motion_vertical_field_select[0][0];
  264.             fpdata.h = 16;
  265.             fpdata.y = by;
  266.             fpdata.dx = PMV[0][0][0];
  267.             fpdata.dy = PMV[0][0][1];
  268.  
  269.             form_prediction(&fpdata, stwtop);
  270.  
  271. //          form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0,
  272. //            Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by,
  273. //            PMV[0][0][0],PMV[0][0][1],stwtop);
  274.         }
  275.       }
  276.       else if (motion_type==MC_16X8)
  277.       {
  278.         if (stwtop<2)
  279.         {
  280.             fpdata.sfield = motion_vertical_field_select[0][0];
  281.             fpdata.h = 8;
  282.             fpdata.y = by;
  283.             fpdata.dx = PMV[0][0][0];
  284.             fpdata.dy = PMV[0][0][1];
  285.  
  286.             form_prediction(&fpdata, stwtop);
  287.  
  288. //          form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0,
  289. //            Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by,
  290. //            PMV[0][0][0],PMV[0][0][1],stwtop);
  291.  
  292.  
  293.           /* determine which frame to use for lower half prediction */
  294.  
  295.           if ((picture_coding_type==P_TYPE) && Second_Field
  296.              && (currentfield!=motion_vertical_field_select[1][0]))
  297.             predframe = backward_reference_frame; /* same frame */
  298.           else
  299.             predframe = forward_reference_frame; /* previous frame */
  300.  
  301.             fpdata.src = predframe;
  302.             fpdata.sfield = motion_vertical_field_select[1][0];
  303.             fpdata.y = by+8;
  304.             fpdata.dx = PMV[1][0][0];
  305.             fpdata.dy = PMV[1][0][1];
  306.  
  307.             form_prediction(&fpdata, stwtop);
  308.  
  309. //          form_prediction(predframe,motion_vertical_field_select[1][0],current_frame,0,
  310. //            Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by+8,
  311. //            PMV[1][0][0],PMV[1][0][1],stwtop);
  312.         }
  313.       }
  314.       else if (motion_type==MC_DMV) /* dual prime prediction */
  315.       {
  316.         if (Second_Field)
  317.           predframe = backward_reference_frame; /* same frame */
  318.         else
  319.           predframe = forward_reference_frame; /* previous frame */
  320.  
  321.         /* calculate derived motion vectors */
  322.         Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]);
  323.  
  324.             fpdata.src = forward_reference_frame;
  325.             fpdata.sfield = currentfield;
  326.             fpdata.h = 16;
  327.             fpdata.y = by;
  328.             fpdata.dx = PMV[0][0][0];
  329.             fpdata.dy = PMV[0][0][1];
  330.  
  331.             form_prediction(&fpdata, 0);
  332.  
  333.         /* predict from field of same parity */
  334. //        form_prediction(forward_reference_frame,currentfield,current_frame,0,
  335. //          Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by,
  336. //          PMV[0][0][0],PMV[0][0][1],0);
  337.  
  338.             fpdata.src = predframe;
  339.             fpdata.sfield = !currentfield;
  340.             fpdata.dx = DMV[0][0];
  341.             fpdata.dy = DMV[0][1];
  342.  
  343.             form_prediction(&fpdata, 1);
  344.  
  345. //        /* predict from field of opposite parity */
  346. //        form_prediction(predframe,!currentfield,current_frame,0,
  347. //          Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by,
  348. //          DMV[0][0],DMV[0][1],1);
  349.       }
  350. //      else
  351. //        /* invalid motion_type */
  352. //        printf("invalid motion_type\n");
  353.     }
  354.     stwtop = stwbot = 1;
  355.   }
  356.  
  357.   if (macroblock_type & MACROBLOCK_MOTION_BACKWARD)
  358.   {
  359.     fpdata.src = backward_reference_frame;
  360.     fpdata.dst = current_frame;
  361.     fpdata.lx2 = Coded_Picture_Width<<1;
  362.  
  363.     if (picture_structure==FRAME_PICTURE)
  364.     {
  365.       fpdata.h = 8;
  366.  
  367.       if (motion_type==MC_FRAME)
  368.       {
  369.         fpdata.lx = Coded_Picture_Width;
  370.         fpdata.y = by;
  371.         fpdata.dx = PMV[0][1][0];
  372.         fpdata.dy = PMV[0][1][1];
  373.  
  374.         /* frame-based prediction */
  375.         if (stwtop<2)
  376.         {
  377.             fpdata.sfield = 0;
  378.             fpdata.dfield = 0;
  379.             form_prediction(&fpdata, stwtop);
  380.  
  381. //          form_prediction(backward_reference_frame,0,current_frame,0,
  382. //            Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
  383. //            PMV[0][1][0],PMV[0][1][1],stwtop);
  384.         }
  385.  
  386.         if (stwbot<2)
  387.         {
  388.             fpdata.sfield = 1;
  389.             fpdata.dfield = 1;
  390.             form_prediction(&fpdata, stwbot);
  391.  
  392. //          form_prediction(backward_reference_frame,1,current_frame,1,
  393. //            Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by,
  394. //            PMV[0][1][0],PMV[0][1][1],stwbot);
  395.         }
  396.       }
  397.       else /* field-based prediction */
  398.       {
  399.         fpdata.lx = Coded_Picture_Width<<1;
  400.         fpdata.y = by>>1;
  401.  
  402.         /* top field prediction */
  403.         if (stwtop<2)
  404.         {
  405.             fpdata.sfield = motion_vertical_field_select[0][1];
  406.             fpdata.dfield = 0;
  407.             fpdata.dx = PMV[0][1][0];
  408.             fpdata.dy = PMV[0][1][1];
  409.  
  410.             form_prediction(&fpdata, stwtop);
  411.  
  412. //          form_prediction(backward_reference_frame,motion_vertical_field_select[0][1],
  413. //            current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
  414. //            bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,stwtop);
  415.         }
  416.  
  417.         /* bottom field prediction */
  418.         if (stwbot<2)
  419.         {
  420.             fpdata.sfield = motion_vertical_field_select[1][1];
  421.             fpdata.dfield = 1;
  422.             fpdata.dx = PMV[1][1][0];
  423.             fpdata.dy = PMV[1][1][1];
  424.  
  425.             form_prediction(&fpdata, stwbot);
  426.  
  427. //          form_prediction(backward_reference_frame,motion_vertical_field_select[1][1],
  428. //            current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
  429. //            bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,stwbot);
  430.         }
  431.       }
  432.     }
  433.     else /* TOP_FIELD or BOTTOM_FIELD */
  434.     {
  435.       fpdata.lx = Coded_Picture_Width<<1;
  436.       fpdata.dfield = 0;
  437.       fpdata.y = by;
  438.       fpdata.dx = PMV[0][1][0];
  439.       fpdata.dy = PMV[0][1][1];
  440.  
  441.       /* field picture */
  442.       if (motion_type==MC_FIELD)
  443.       {
  444.             fpdata.sfield = motion_vertical_field_select[0][1];
  445.             fpdata.h = 16;
  446.  
  447.             form_prediction(&fpdata, stwtop);
  448.  
  449.         /* field-based prediction */
  450. //        form_prediction(backward_reference_frame,motion_vertical_field_select[0][1],
  451. //          current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,
  452. //          bx,by,PMV[0][1][0],PMV[0][1][1],stwtop);
  453.       }
  454.       else if (motion_type==MC_16X8)
  455.       {
  456.             fpdata.sfield = motion_vertical_field_select[0][1];
  457.             fpdata.h = 8;
  458.  
  459.             form_prediction(&fpdata, stwtop);
  460.  
  461. //        form_prediction(backward_reference_frame,motion_vertical_field_select[0][1],
  462. //          current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
  463. //          bx,by,PMV[0][1][0],PMV[0][1][1],stwtop);
  464.  
  465.             fpdata.sfield = motion_vertical_field_select[1][1];
  466.             fpdata.y = by+8;
  467.             fpdata.dx = PMV[1][1][0];
  468.             fpdata.dy = PMV[1][1][1];
  469.  
  470.             form_prediction(&fpdata, stwtop);
  471.  
  472. //        form_prediction(backward_reference_frame,motion_vertical_field_select[1][1],
  473. //          current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,
  474. //          bx,by+8,PMV[1][1][0],PMV[1][1][1],stwtop);
  475.         }
  476. //      else
  477. //        /* invalid motion_type */
  478. //        printf("invalid motion_type\n");
  479.     }
  480.   }
  481. }
  482.  
  483.  
  484.  
  485.  
  486.  
  487. #ifndef ASSEMBLER_OPTIMIZATION
  488.  
  489.  
  490. static void form_prediction(struct fpdata *f, int average_flag)
  491. {
  492.   form_component_prediction(
  493.       f->src[0]+(f->sfield?f->lx2>>1:0),f->dst[0]+(f->dfield?f->lx2>>1:0),
  494.       f->lx,f->lx2,f->w,f->h,f->x,f->y,f->dx,f->dy,average_flag);
  495.  
  496.   if (!opts[OPT_GREY])
  497.   {
  498.     int lx = f->lx, lx2 = f->lx2, w = f->w,
  499.         x = f->x, dx = f->dx, h = f->h, y = f->y, dy = f->dy;
  500.     
  501.       if (chroma_format!=CHROMA444)
  502.       {
  503.           lx >>= 1;
  504.           lx2 >>= 1;
  505.           w >>= 1;
  506.           x >>= 1;
  507.           dx >>= 1;
  508.       }
  509.  
  510.       if (chroma_format==CHROMA420)
  511.       {
  512.           h >>= 1;
  513.           y >>= 1;
  514.           dy >>= 1;
  515.       }
  516.  
  517.       /* Cb */
  518.       form_component_prediction(f->src[1]+(f->sfield?lx2>>1:0),
  519.           f->dst[1]+(f->dfield?lx2>>1:0),
  520.         lx,lx2,w,h,x,y,dx,dy,average_flag);
  521.  
  522.       /* Cr */
  523.       form_component_prediction(f->src[2]+(f->sfield?lx2>>1:0),
  524.           f->dst[2]+(f->dfield?lx2>>1:0),
  525.         lx,lx2,w,h,x,y,dx,dy,average_flag);
  526.   }
  527.  
  528.  
  529. }
  530.  
  531.  
  532.  
  533. /* ISO/IEC 13818-2 section 7.6.4: Forming predictions */
  534. /* NOTE: the arithmetic below produces numerically equivalent results
  535.  *  to 7.6.4, yet is more elegant. It differs in the following ways:
  536.  *
  537.  *   1. the vectors (dx, dy) are based on cartesian frame 
  538.  *      coordiantes along a half-pel grid (always positive numbers)
  539.  *      In contrast, vector[r][s][t] are differential (with positive and 
  540.  *      negative values). As a result, deriving the integer vectors 
  541.  *      (int_vec[t]) from dx, dy is accomplished by a simple right shift.
  542.  *
  543.  *   2. Half pel flags (xh, yh) are equivalent to the LSB (Least
  544.  *      Significant Bit) of the half-pel coordinates (dx,dy).
  545.  * 
  546.  *
  547.  *  NOTE: the work of combining predictions (ISO/IEC 13818-2 section 7.6.7)
  548.  *  is distributed among several other stages.  This is accomplished by 
  549.  *  folding line offsets into the source and destination (src,dst)
  550.  *  addresses (note the call arguments to form_prediction() in Predict()),
  551.  *  line stride variables lx and lx2, the block dimension variables (w,h), 
  552.  *  average_flag, and by the very order in which Predict() is called.  
  553.  *  This implementation design (implicitly different than the spec) 
  554.  *  was chosen for its elegance.
  555. */
  556.  
  557. static void __inline form_component_prediction(src,dst,lx,lx2,w,h,x,y,dx,dy,average_flag)
  558. unsigned char *src;
  559. unsigned char *dst;
  560. int lx;          /* raster line increment */ 
  561. int lx2;
  562. int w,h;
  563. int x,y;
  564. int dx,dy;
  565. int average_flag;      /* flag that signals bi-directional or Dual-Prime 
  566.                           averaging (7.6.7.1 and 7.6.7.4). if average_flag==1,
  567.                           a previously formed prediction has been stored in 
  568.                           pel_pred[] */
  569. {
  570.   int xint;      /* horizontal integer sample vector: analogous to int_vec[0] */
  571.   int yint;      /* vertical integer sample vectors: analogous to int_vec[1] */
  572.   int xh;        /* horizontal half sample flag: analogous to half_flag[0]  */
  573.   int yh;        /* vertical half sample flag: analogous to half_flag[1]  */
  574.   int i, j, v;
  575.   unsigned char *s;    /* source pointer: analogous to pel_ref[][]   */
  576.   unsigned char *d;    /* destination pointer:  analogous to pel_pred[][]  */
  577.  
  578.     unsigned char *ts, *td, *ts2;
  579.  
  580.   /* half pel scaling for integer vectors */
  581.   xint = dx>>1;
  582.   yint = dy>>1;
  583.  
  584.   /* derive half pel flags */
  585.   xh = dx & 1;
  586.   yh = dy & 1;
  587.  
  588.   /* compute the linear address of pel_ref[][] and pel_pred[][] 
  589.      based on cartesian/raster cordinates provided */
  590.   s = src + lx*(y+yint) + x + xint;
  591.   d = dst + lx*y + x;
  592.  
  593.   if (!xh && !yh) /* no horizontal nor vertical half-pel */
  594.   {
  595.     if (average_flag)
  596.     {
  597.       for (j=0; j<h; j++)
  598.       {
  599.           ts = s;
  600.           td = d;
  601.         for (i=0; i<w; i+=4)
  602.         {
  603.             *td = (unsigned char) ((*td + *ts + 1) >> 1); td++; ts++;
  604.             *td = (unsigned char) ((*td + *ts + 1) >> 1); td++; ts++;
  605.             *td = (unsigned char) ((*td + *ts + 1) >> 1); td++; ts++;
  606.             *td = (unsigned char) ((*td + *ts + 1) >> 1); td++; ts++;
  607.         }
  608.         s+= lx2;
  609.         d+= lx2;
  610.       }
  611.     }
  612.     else
  613.     {
  614.       for (j=0; j<h; j++)
  615.       {
  616.           ts = s;
  617.           td = d;
  618.         for (i=0; i<w; i+=4)
  619.         {
  620.           *td++ = *ts++;
  621.           *td++ = *ts++;
  622.           *td++ = *ts++;
  623.           *td++ = *ts++;
  624.         }
  625.         
  626.         s+= lx2;
  627.         d+= lx2;
  628.       }
  629.     }
  630.   }
  631.   else if (!xh && yh) /* no horizontal but vertical half-pel */
  632.   {
  633.     if (average_flag)
  634.     {
  635.       for (j=0; j<h; j++)
  636.       {
  637.           ts = s;
  638.           ts2 = s + lx;
  639.           td = d;
  640.         for (i=0; i<w; i+=4)
  641.         {
  642.             *td = (*td + ((*ts + *ts2 + 1) >> 1) + 1) >> 1; td++; ts++; ts2++;
  643.             *td = (*td + ((*ts + *ts2 + 1) >> 1) + 1) >> 1; td++; ts++; ts2++;
  644.             *td = (*td + ((*ts + *ts2 + 1) >> 1) + 1) >> 1; td++; ts++; ts2++;
  645.             *td = (*td + ((*ts + *ts2 + 1) >> 1) + 1) >> 1; td++; ts++; ts2++;
  646.         }
  647.         s+= lx2;
  648.         d+= lx2;
  649.       }
  650.     }
  651.     else
  652.     {
  653.       for (j=0; j<h; j++)
  654.       {
  655.           ts = s;
  656.           ts2 = s + lx;
  657.           td = d;
  658.         for (i=0; i<w; i+=4)
  659.         {
  660.             *td++ = (*ts + *ts2 + 1) >> 1; ts++; ts2++;
  661.             *td++ = (*ts + *ts2 + 1) >> 1; ts++; ts2++;
  662.             *td++ = (*ts + *ts2 + 1) >> 1; ts++; ts2++;
  663.             *td++ = (*ts + *ts2 + 1) >> 1; ts++; ts2++;
  664.         }
  665.  
  666.         s+= lx2;
  667.         d+= lx2;
  668.       }
  669.     }
  670.   }
  671.   else if (xh && !yh) /* horizontal but no vertical half-pel */
  672.   {
  673.     if (average_flag)
  674.     {
  675.       for (j=0; j<h; j++)
  676.       {
  677.           ts = s;
  678.           td = d;
  679.         for (i=0; i<w; i+=4)
  680.         {
  681.             *td = (*td + ((*ts++ + *ts + 1) >> 1)) >> 1; *td++;
  682.             *td = (*td + ((*ts++ + *ts + 1) >> 1)) >> 1; *td++;
  683.             *td = (*td + ((*ts++ + *ts + 1) >> 1)) >> 1; *td++;
  684.             *td = (*td + ((*ts++ + *ts + 1) >> 1)) >> 1; *td++;
  685.         }
  686.      
  687.         s+= lx2;
  688.         d+= lx2;
  689.       }
  690.     }
  691.     else
  692.     {
  693.       for (j=0; j<h; j++)
  694.       {
  695.       
  696.           ts = s;
  697.           td = d;
  698.         for (i=0; i<w; i+=4)
  699.         {
  700.             *td++ = (*ts++ + *ts + 1) >> 1;
  701.             *td++ = (*ts++ + *ts + 1) >> 1;
  702.             *td++ = (*ts++ + *ts + 1) >> 1;
  703.             *td++ = (*ts++ + *ts + 1) >> 1;
  704.         }
  705.  
  706.         s+= lx2;
  707.         d+= lx2;
  708.       }
  709.     }
  710.   }
  711.   else /* if (xh && yh) horizontal and vertical half-pel */
  712.   {
  713.     if (average_flag)
  714.     {
  715.       for (j=0; j<h; j++)
  716.       {
  717.  
  718.           ts = s;
  719.           ts2 = s + lx;
  720.           td = d;
  721.  
  722.         for (i=0; i<w; i+=4)
  723.         {
  724.             *td = (*td + ((*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2) + 1) >> 1; *td++;
  725.             *td = (*td + ((*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2) + 1) >> 1; *td++;
  726.             *td = (*td + ((*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2) + 1) >> 1; *td++;
  727.             *td = (*td + ((*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2) + 1) >> 1; *td++;
  728.         }
  729.      
  730.         s+= lx2;
  731.         d+= lx2;
  732.       }
  733.     }
  734.     else
  735.     {
  736.       for (j=0; j<h; j++)
  737.       {
  738.  
  739.           ts = s;
  740.           ts2 = s + lx;
  741.           td = d;
  742.         for (i=0; i<w; i+=4)
  743.         {
  744.             *td++ = (*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2;
  745.             *td++ = (*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2;
  746.             *td++ = (*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2;
  747.             *td++ = (*ts++ + *ts + *ts2++ + *ts2 + 2) >> 2;
  748.         }
  749.  
  750.         s+= lx2;
  751.         d+= lx2;
  752.       }
  753.     }
  754.   }
  755. }
  756.  
  757. #endif
  758.  
  759.  
  760.  
  761.  
  762. //////////////////////////////////////////////////////////////////
  763. //////////////////////////////////////////////////////////////////
  764. /////////////////////////// obsolete /////////////////////////////
  765. //////////////////////////////////////////////////////////////////
  766. //////////////////////////////////////////////////////////////////
  767.  
  768. #if 0
  769.  
  770. static void
  771.  
  772. #ifdef ASSEMBLER_OPTIMIZATION
  773. __inline
  774. #endif
  775.  
  776. form_prediction(src,sfield,dst,dfield,lx,lx2,w,h,x,y,dx,dy,average_flag)
  777. unsigned char *src[]; /* prediction source buffer */
  778. int sfield;           /* prediction source field number (0 or 1) */
  779. unsigned char *dst[]; /* prediction destination buffer */
  780. int dfield;           /* prediction destination field number (0 or 1)*/
  781. int lx,lx2;           /* line strides */
  782. int w,h;              /* prediction block/sub-block width, height */
  783. int x,y;              /* pixel co-ordinates of top-left sample in current MB */
  784. int dx,dy;            /* horizontal, vertical prediction address */
  785. int average_flag;     /* add prediction error to prediction ? */
  786. {
  787.  
  788.   /* Y */
  789.   form_component_prediction(src[0]+(sfield?lx2>>1:0),dst[0]+(dfield?lx2>>1:0),
  790.     lx,lx2,w,h,x,y,dx,dy,average_flag);
  791.  
  792.   if (!opts[OPT_GREY])
  793.   {
  794.  
  795.       if (chroma_format!=CHROMA444)
  796.       {
  797.         lx>>=1; lx2>>=1; w>>=1; x>>=1; dx/=2;
  798.       }
  799.  
  800.       if (chroma_format==CHROMA420)
  801.       {
  802.         h>>=1; y>>=1; dy/=2;
  803.       }
  804.  
  805.       /* Cb */
  806.       form_component_prediction(src[1]+(sfield?lx2>>1:0),dst[1]+(dfield?lx2>>1:0),
  807.         lx,lx2,w,h,x,y,dx,dy,average_flag);
  808.  
  809.       /* Cr */
  810.       form_component_prediction(src[2]+(sfield?lx2>>1:0),dst[2]+(dfield?lx2>>1:0),
  811.         lx,lx2,w,h,x,y,dx,dy,average_flag);
  812.   }
  813.  
  814. }
  815.  
  816. #endif
  817.